#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "aodv_socket.h"
#include "aodv_packet.h"
#include "aodv_types.h"
#include "aodv_routing_table.h"
#include "aodv_rreq.h"  // 添加 RREQ 处理头文件
#include "aodv_rrep.h"  // 添加 RREP 处理头文件
#include "aodv_rerr.h"  // 添加 RERR 处理头文件
#include "aodv_forward.h" // 添加数据转发头文件
#include "aodv_hello.h" // 添加Hello消息处理头文件

int main() {
    // 初始化Winsock
    if (aodv_socket_init() != 0) {
        fprintf(stderr, "Winsock initialization failed.\n");
        return 1;
    }

    // 假设当前节点的IP地址为 127.0.0.1
    uint32_t local_ip = inet_addr("127.0.0.1");

    // 创建并绑定UDP套接字
    SOCKET sock = aodv_socket_create_and_bind(local_ip);
    if (sock == INVALID_SOCKET) {
        aodv_socket_cleanup();
        return 1;
    }

    printf("AODV Node started on %s:%d\n", inet_ntoa(*(struct in_addr*)&local_ip), AODV_PORT);

    // 初始化路由表
    aodv_routing_table routing_table;
    routing_table_init(&routing_table);

    // 初始化 RREQ ID 缓存
    rreq_id_cache rreq_cache;
    rreq_id_cache_init(&rreq_cache);

    // 初始化数据转发模块
    forward_stats_t forward_stats;
    forward_init(&forward_stats);

    // 启动Hello定时器
    uint32_t broadcast_addr = inet_addr("255.255.255.255");
    start_hello_timer(sock, local_ip, broadcast_addr, &routing_table);
    printf("Hello timer started for neighbor discovery\n");

    // 初始化序列号和RREQ ID
    uint32_t sequence_number = 1;
    uint16_t rreq_id_counter = 1;

    // 示例：添加一些路由条目用于测试
    routing_table_entry entry1 = {
        .dest_addr = inet_addr("127.0.0.2"),
        .dest_seq_num = 10,
        .next_hop_addr = inet_addr("127.0.0.2"),
        .hop_count = 1,
        .lifetime = (uint32_t)time(NULL) + 60
    };
    routing_table_add_or_update(&routing_table, &entry1);

    // 示例1：发送 RREQ 到未知目标
    printf("\n=== Test 1: Sending RREQ to unknown destination ===\n");
    uint32_t unknown_dest = inet_addr("127.0.0.4");
    send_rreq(unknown_dest, 0, local_ip, sock, &routing_table);

    // 示例2：发送 RREQ 到已知目标（应该跳过）
    printf("\n=== Test 2: Sending RREQ to known destination ===\n");
    uint32_t known_dest = inet_addr("127.0.0.2");
    send_rreq(known_dest, 0, local_ip, sock, &routing_table);

    // 示例3：模拟接收 RREQ 并处理
    printf("\n=== Test 3: Processing received RREQ ===\n");
    aodv_rreq test_rreq;
    build_rreq_packet(&test_rreq, 123, inet_addr("127.0.0.3"), 5, inet_addr("127.0.0.5"), 2, 0);
    
    // 模拟处理接收到的 RREQ
    process_rreq_message(&test_rreq, inet_addr("127.0.0.2"), &routing_table, &rreq_cache, local_ip);

    // 示例4：测试 RREQ ID 缓存
    printf("\n=== Test 4: Testing RREQ ID cache ===\n");
    if (rreq_id_cache_contains(&rreq_cache, inet_addr("127.0.0.5"), 123)) {
        printf("RREQ ID 123 from 127.0.0.5 found in cache (correct)\n");
    } else {
        printf("RREQ ID 123 from 127.0.0.5 not found in cache (error)\n");
    }

    // 示例5：测试重复 RREQ 处理
    printf("\n=== Test 5: Processing duplicate RREQ ===\n");
    process_rreq_message(&test_rreq, inet_addr("127.0.0.2"), &routing_table, &rreq_cache, local_ip);

    // 示例6：测试 RREP 消息处理
    printf("\n=== Test 6: Processing RREP message ===\n");
    aodv_rrep test_rrep_msg;
    build_rrep_packet(&test_rrep_msg, inet_addr("127.0.0.3"), 15, inet_addr("127.0.0.1"), 5, 2, 5000);
    
    // 模拟处理接收到的 RREP（当前节点是目标）
    int rrep_result = process_rrep_message(&test_rrep_msg, inet_addr("127.0.0.2"), &routing_table, local_ip);
    if (rrep_result == 1) {
        printf("RREP processing completed successfully - route established!\n");
    }

    // 示例7：测试无效 RREP 处理
    printf("\n=== Test 7: Processing invalid RREP ===\n");
    aodv_rrep invalid_rrep_msg;
    build_rrep_packet(&invalid_rrep_msg, inet_addr("127.0.0.4"), 20, inet_addr("127.0.0.1"), 10, 300, 500); // 跳数过多
    
    process_rrep_message(&invalid_rrep_msg, inet_addr("127.0.0.2"), &routing_table, local_ip);

    // 示例8：测试数据转发功能
    printf("\n=== Test 8: Testing data forwarding ===\n");
    
    // 测试1：发送到已知目标的数据包
    const char* test_data1 = "Hello, this is test data!";
    forward_result_t result1 = forward_data_packet(sock, local_ip, inet_addr("127.0.0.2"), 
                                                  test_data1, strlen(test_data1), 
                                                  &routing_table, &sequence_number, &rreq_id_counter);
    printf("Forward result to known destination: %s\n", 
           result1 == FORWARD_SUCCESS ? "SUCCESS" : "FAILED");
    
    // 测试2：发送到未知目标的数据包（应该触发路由发现）
    const char* test_data2 = "Data to unknown destination";
    forward_result_t result2 = forward_data_packet(sock, local_ip, inet_addr("127.0.0.5"), 
                                                  test_data2, strlen(test_data2), 
                                                  &routing_table, &sequence_number, &rreq_id_counter);
    printf("Forward result to unknown destination: %s\n", 
           result2 == FORWARD_ROUTE_DISCOVERY_NEEDED ? "ROUTE DISCOVERY NEEDED" : 
           result2 == FORWARD_SUCCESS ? "SUCCESS" : "FAILED");
    
    // 测试3：模拟接收数据包处理
    printf("\n=== Test 9: Testing received packet processing ===\n");
    data_packet_header_t recv_header;
    recv_header.dest_addr = local_ip;
    recv_header.src_addr = inet_addr("127.0.0.2");
    recv_header.packet_id = generate_packet_id();
    recv_header.packet_type = PACKET_TYPE_DATA;
    recv_header.data_len = strlen(test_data1);
    recv_header.timestamp = (uint32_t)time(NULL);
    
    // 构建完整的数据包
    uint8_t recv_packet[sizeof(data_packet_header_t) + strlen(test_data1)];
    memcpy(recv_packet, &recv_header, sizeof(data_packet_header_t));
    memcpy(recv_packet + sizeof(data_packet_header_t), test_data1, strlen(test_data1));
    
    // 模拟接收到的数据包
    forward_result_t result3 = process_received_packet(sock, recv_packet, sizeof(recv_packet), 
                                                    inet_addr("127.0.0.2"), &routing_table,
                                                    local_ip, &sequence_number, &rreq_id_counter);
    printf("Received packet processing result: %s\n", 
           result3 == FORWARD_SUCCESS ? "SUCCESS" : "FAILED");

    // 打印转发统计
    printf("\n=== Forwarding Statistics ===\n");
    char stats_buffer[512];
    get_forward_stats(&forward_stats, stats_buffer, sizeof(stats_buffer));
    printf("%s", stats_buffer);

    // 示例10：测试 RERR 消息处理
    printf("\n=== Test 10: Testing RERR message processing ===\n");
    
    // 测试1：构建和验证RERR消息
    aodv_rerr test_rerr;
    uint32_t unreachable_dest = inet_addr("127.0.0.6");
    uint32_t unreachable_dest_seq = 25;
    
    build_rerr_packet_with_type(&test_rerr, unreachable_dest, unreachable_dest_seq, RERR_DEST_UNREACHABLE);
    
    if (validate_rerr_message(&test_rerr)) {
        printf("RERR packet validation: SUCCESS\n");
    } else {
        printf("RERR packet validation: FAILED\n");
    }
    
    // 测试2：处理RERR消息（应该使相关路由失效）
    printf("Processing RERR message...\n");
    process_rerr_message(&test_rerr, inet_addr("127.0.0.2"), &routing_table, local_ip);
    
    // 检查路由是否被标记为无效
    routing_table_entry *affected_route = routing_table_find(&routing_table, unreachable_dest);
    if (affected_route == NULL) {
        printf("Route to %s was removed due to RERR (correct)\n", 
               inet_ntoa(*(struct in_addr*)&unreachable_dest));
    } else if (!routing_table_is_valid(&routing_table, unreachable_dest)) {
        printf("Route to %s was marked as invalid due to RERR (correct)\n", 
               inet_ntoa(*(struct in_addr*)&unreachable_dest));
    } else {
        printf("Route to %s still valid after RERR (unexpected)\n", 
               inet_ntoa(*(struct in_addr*)&unreachable_dest));
    }
    
    // 测试3：模拟链路故障检测（通过数据转发失败触发RERR）
    printf("\n=== Test 11: Testing RERR triggered by forwarding failure ===\n");
    
    // 添加一个路由，其下一跳是"不可达"的地址（会触发发送失败）
    routing_table_entry problematic_route = {
        .dest_addr = inet_addr("127.0.0.7"),
        .dest_seq_num = 30,
        .next_hop_addr = inet_addr("127.0.0.99"), // 这个地址会导致sendto失败
        .hop_count = 2,
        .lifetime = (uint32_t)time(NULL) + 60
    };
    routing_table_add_or_update(&routing_table, &problematic_route);
    
    // 尝试发送数据包，应该会失败并触发RERR
    const char* test_data3 = "Data that should trigger RERR";
    forward_result_t result4 = forward_data_packet(sock, local_ip, inet_addr("127.0.0.7"), 
                                                  test_data3, strlen(test_data3), 
                                                  &routing_table, &sequence_number, &rreq_id_counter);
    printf("Forward result to problematic destination: %s\n", 
           result4 == FORWARD_SEND_FAILED ? "SEND FAILED (RERR triggered)" : "OTHER");

    // 打印最终的路由表状态
    printf("\n=== Final Routing Table ===\n");
    routing_table_print(&routing_table);

    // 测试12：测试Hello消息处理
    printf("\n=== Test 12: Testing Hello message processing ===\n");
    
    // 测试1：构建和验证Hello消息
    aodv_hello test_hello;
    if (build_hello_packet(&test_hello, 5000) == 0) {  // 5秒生命周期
        printf("Hello packet built successfully\n");
        
        if (validate_hello_message(&test_hello, sizeof(aodv_hello))) {
            printf("Hello packet validation: SUCCESS\n");
        } else {
            printf("Hello packet validation: FAILED\n");
        }
    }
    
    // 测试2：处理Hello消息（应该添加邻居）
    printf("Processing Hello message...\n");
    process_hello_message(&test_hello, inet_addr("127.0.0.8"), &routing_table, local_ip);
    
    // 检查邻居是否被添加
    routing_table_entry *hello_route = routing_table_find(&routing_table, inet_addr("127.0.0.8"));
    if (hello_route != NULL && hello_route->hop_count == 1) {
        printf("Hello message added neighbor 127.0.0.8 (correct)\n");
    } else {
        printf("Hello message did not add neighbor 127.0.0.8 (unexpected)\n");
    }
    
    // 测试3：检查邻居超时
    printf("\n=== Test 13: Testing neighbor timeout check ===\n");
    
    // 手动设置一个邻居为过期
    routing_table_entry old_neighbor = {
        .dest_addr = inet_addr("127.0.0.9"),
        .dest_seq_num = 5,
        .next_hop_addr = inet_addr("127.0.0.9"),
        .hop_count = 1,
        .lifetime = (uint32_t)time(NULL) - 10  // 已经过期
    };
    routing_table_add_or_update(&routing_table, &old_neighbor);
    
    printf("Checking neighbor timeouts...\n");
    check_neighbor_timeout(&routing_table, local_ip, (uint32_t)time(NULL));
    
    // 检查过期邻居是否被移除
    routing_table_entry *expired_neighbor = routing_table_find(&routing_table, inet_addr("127.0.0.9"));
    if (expired_neighbor == NULL) {
        printf("Expired neighbor 127.0.0.9 was removed (correct)\n");
    } else {
        printf("Expired neighbor 127.0.0.9 still exists (unexpected)\n");
    }

    // 清理
    stop_hello_timer();  // 停止Hello定时器
    forward_cleanup();
    closesocket(sock);
    aodv_socket_cleanup();

    return 0;
}